Logto Auth 🤎 Svelte

Svelte and auth?

If you know a little bit about Javascript frameworks, you have heard about Svelte and Sveltekit.

Even if it's less known than React, Angular or Vue, it's also much more pleasant to code and to adapt to your needs.

If you knew Meteor back in the day when it provided authentication and hosting in a simple and free way (2016), you might find that newer frameworks are sorely lacking in easy-to-implement and flexible authentication solutions.

When I say flexible solutions, I mean a solution that starts free for your MVP, that you can continue on the cloud but that you can also host on your servers. Auth0 is not totally flexible for example, when your user base grows, you can only pay them more.

Why would you want to host?

Vocamen develops a free multiplayer Christian game in HTML5. Like all web projects, it aims to reach millions of people, whether they are casual or regular players. In terms of authentication, this means that we should pay after a certain number of users. If we ask our players to pay for the right to play, even if we explain our constraint, we expect that about 90% will leave, especially the casual players, the community would be reduced, thus the life around the game, thus an essential part of the interest of this game. It is the passage to critical mass that becomes very delicate, even to a possible total sclerosis of the game, all because of a choice of outsourced service instead of being controlled internally.

On the other hand, managing authentication simply in the same database as the rest of the game is very dangerous. Some players want to try to force their way through the game to increase their score, have all the options, validate all the levels, be the first to win, or prevent others from winning. It's a game within a game for them, but it destroys the game for everyone. To do this, they will flood the authentication with login attempts, create multiple fake users (more dollars spent uselessly), use brute force using password dictionaries, etc.

Therefore, several countermeasures must be put in place: The first is to specialize the authentication service. A solution that only manages authentication is designed to resist intrusions. It is the authentication service that will be attacked and not the game itself. The second is to throttle the number of requests per second and to impose waiting times on some of them, as well as other countermeasures, and if possible to identify the typology of the attackers to block them more quickly, thus to be able to set up routing upstream of the authentication. It is impossible to control this routing for an external solution, but we do control it for internal services.

Moreover, if we had to rely on an external service like auth0, the response time of the service would depend not only on our distance to the authentication server (ping), but also on the number of joint attacks on the other services hosted by this external solution. Imagine if 1000 games have their authentications hosted, and attacked, at the same location as yours. Of course the external authentication service is designed to block, but it only activates after a certain number of requests, so there is always a part that penalizes the access of your customers.

Last but not least, an internally hosted solution is GDPR compliant. Some external authentication solutions collect IPs, geolocate your customers without you even using the country blocking feature. This non-protection of our users' data would potentially expose us to sanctions.

Solution

Hosted open-source microservices are THE solution to control technically and legally the data and the growth of the game. You just have to increase them according to the success of the game.

Concerning authentication, we needed a simple alternative to Auth0, an open-source and hostable solution. Last week on github, I came across the very recent Logto (https://github.com/logto-io/logto) which explains in the README how to host its solution via docker, which is a sign of a real open-source openness and not only of a will to have free developers. I specify that I am not affiliated to Logto, nor paid to promote it.

After adding my star in the upper right corner, I looked at the proposed clients: React, Vue and Vanilla JS.

(Vanilla is not another Javascript framework, just the little name we give to basic Javascript code, without a framework, just with NodeJS. The basic flavor of ice cream)

One of the advantages of Svelte is to be able to integrate very easily any Javascript library, even if it is not designed for it.

So to integrate the hosted version (to start with) of Logto, you just need to create an account on the logto.io cloud, add a test client and add an application, here a SPA (Single Page App).
Logto gives you the App ID, the endpoint created for your app, and explains how a simple node JS (or React, Vue) client can connect:

npm i @logto/browser

//index.js

import LogtoClient from '@logto/browser';

const logtoClient = new LogtoClient({

endpoint: 'https://j79tk5.logto.app/',

appId: 'DRWBOmiaeIkJtHJQ4catO',

});

<button onclick="logtoClient.signIn('http://localhost:5173')">Sign In</button>

Note that you must specify the callback, i.e. the return URL after the client is connected. To keep it simple, we will use the same page as the login page. As we will perform this test locally, it is the local development version (npm run dev).

Small note: How can an external service call a server internal to your machine? Simply because it is a link followed by your browser, it is at the client level and not at the server level.

When the authentication server sends you back to your site, it adds information about the success or failure of authentication of the user:

try {

await logtoClient.handleSignInCallback(window.location.href);

console.log(logtoClient.isAuthenticated); // true

} catch {

// Handle error

}

Finally, you have a button to log-out:

<button onclick="logtoClient.signOut('http://localhost:5173')">

Sign Out

</button>

To adapt it to Svelte, here's the unique `App.svelte` file:

<script>

import LogtoClient from '@logto/browser';

import { onMount } from 'svelte';

let logtoClient;

onMount(async () => {

logtoClient = new LogtoClient({

endpoint: 'https://j79tk5.logto.app/',

appId: 'DRWBOmiaeIkJtHJQ4catO',

});

// will rerun when client is logged-in, populated with client info

try {

await logtoClient.handleSignInCallback(window.location.href);

console.log(logtoClient);

} catch {

console.log("Not logged-in")

}

});

</script>

<p>Create a user in <a href="https://cloud.logto.io">logto</a></p>

<p>Create a vanilla app and adapt code in the source of this page (src/page.svelte)</p>

<button on:click={logtoClient.signIn('http://localhost:5173')}>

Sign In

</button>

<p>Now open your console to see signed-in client</p>

<p>So easy!</p>

<button on:click={logtoClient.signOut('http://localhost:5173')}>

Sign Out

</button>

You will notice that we just put all the scripts in one place and the HTML buttons follow. It seems too simple.

Note that the callback await logtoClient... refers to the logtoClient instance and not to the LogtoClient library. So it can be used again for the callback.

There were only a few adaptations:

- import { onMount } from 'svelte'; and onMount(async () => { to execute this code once the page is loaded, not before.

- let logtoClient; is a global variable so that it can be called by the HTML code as well as by the script.

- try ... from the callback is also in the onMount

- the onMount is async since the callback has await

- console.log(logtoClient); gives all the user information, plus the JWT token stored in the localSotrage. The latter will be useful for your game to verify that the identified client is telling the truth.

- button onclick="... has become button on:click={... according to svelte design


And that's it!

The code for Svelte is very similar to Vanilla javascript and very easy to understand.

Now you have "outsourced" authentication (on the cloud or your logto container), separate from your database.


There is no feedback implemented in the vocamen site, but you can join the Logto Discord server (https://discord.gg/UEPaF3j5e6) and leave me your encouragement and possible questions (vocamen). I go there from time to time.

I will probably update this page for Sveltekit and expand the possibilities, so feel free to come back.